  1.NameNode如何支撑高并发访问(双缓冲机制)
    
	高并发访问NameNode会遇到什么样的问题：
	经过学习HDFS的元数据管理机制，Client每次请求NameNode修改一条元数据（比如说申请上传一个文件，都要
写一条edits log，包括两个步骤：
    写入本地磁盘--edits文件
    通过网络传输给JournalNodes集群(Hadoop HA集群--结合zookeeper来学习)。
	高并发的难点主要在于数据的多线程安全以及每个操作效率！！
    对于多线程安全：
    NameNode在写edits log时几个原则：
	写入数据到edits_log必须保证每条edits都有一个全局顺序递增的transactionId（简称为txid），这样才可以标识
出来一条一条的edits的先后顺序。
    如果要保证每条edits的txid都是递增的，就必须得加同步锁。也就是每个线程修改了元数据，要写一条edits 的时候
，都必须按顺序排队获取锁后，才能生成一个递增的txid，代表这次要写的edits的序号。
    
	产生的问题：
    如果每次都是在一个加锁的代码块里，生成txid，然后写磁盘文件edits log，这种既有同步锁又有写磁盘操作非常耗时！！
	HDFS优化解决方案
    问题产生的原因主要是在于，写edits时串行化排队生成自增txid + 写磁盘操作费时，
     HDFS的解决方案
     1).串行化：使用分段锁
     2).写磁盘：使用双缓冲
	 分段加锁机制:
	 首先各个线程依次第一次获取锁，生成顺序递增的txid，然后将edits写入内存双缓冲的区域1，接着就立马第一
次释放锁了。趁着这个空隙，后面的线程就可以再次立马第一次获取锁，然后立即写自己的edits到内存缓冲。
     双缓冲机制
	 程序中将会开辟两份一模一样的内存空间，一个为bufCurrent，产生的数据会直接写入到这个bufCurrent，而另一个
叫bufReady，在bufCurrent数据写入(达到一定标准)后，两片内存就会exchange（交换）。直接交换双缓冲的区域1和区域
2。 保证接收客户端写入数据请求的都是操作内存而不是同步写磁盘。
     双缓冲源码分析 找到FsEditLog.java
	 
	 ....
  void logEdit(final FSEditLogOp op) {
  boolean needsSync = false;//是否同步的标识
  synchronized (this) {//
   assert isOpenForWrite() :
       "bad state: " + state;
   // wait if an automatic sync is scheduled 如果当前操作被其它线程调度，则等待1s钟
   waitIfAutoSyncScheduled();
   // check if it is time to schedule an automatic sync
   needsSync = doEditTransaction(op);
   if (needsSync) {
    isAutoSyncScheduled = true;//标识bufCurrent满了，进行双缓冲刷写
  }
 }
  // Sync the log if an automatic sync is required.
  if (needsSync) {
   logSync();//将缓冲区数据刷写到磁盘
 }
} 
 
 ...